﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace ExcelColumnSplitter
{
    public class Presets
    {
        public string SourceAddress { get; set; } = "";
        public string TargetAddress { get; set; } = "";
        public List<string> Separators { get; set; } = new List<string>();
        public List<Extraction> Extractions { get; set; } = new List<Extraction>();
        public bool FilterEmptyInput { get; set; } = false;
        public bool FilterEmptyResult { get; set; } = false;
        public bool EnableGroupLimit { get; set; } = false;
        public int GroupLimit { get; set; } = 0;
    }

    // C:\Users\[username]\AppData\Local\Apps\2.0\Data\[something]\[something else]\exce..vsto_...\Data\[excel version]
    public class AppSettings: ApplicationSettingsBase
    {
        private static readonly object InstanceLock = new object();
        private static AppSettings _instance = null;
        public static AppSettings Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (InstanceLock)
                    {
                        if (_instance == null)
                        {
                            _instance = new AppSettings();
                        }
                    }
                }
                return _instance;
            }
        }

        public AppSettings()
        {
            if(this.Presets == null)
            {
                this.Presets = new PresetsDictionary();
            }
        }

        [UserScopedSetting()]
        [SettingsSerializeAs(SettingsSerializeAs.Xml)]
        public string Version
        {
            get { return (string)this["Version"]; }
            set { this["Version"] = value; }
        }

        [UserScopedSetting]
        [DefaultSettingValue("Hello, World!")]
        public string Greeting
        {
            get { return (string)this["Greeting"]; }
            set { this["Greeting"] = value; }
        }

        [UserScopedSetting()]
        [SettingsSerializeAs(SettingsSerializeAs.Xml)]
        public PresetsDictionary Presets
        {
            get { return (PresetsDictionary)this["Presets"]; }
            set { this["Presets"] = value; }
        }
    }

    public class PresetsDictionary: Dictionary<string, Presets>, IXmlSerializable
    {
        public XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            var xmlSerializer = new XmlSerializer(typeof(Presets));
            while (reader.Read() &&
            !(reader.NodeType == System.Xml.XmlNodeType.EndElement && reader.LocalName == this.GetType().Name))
            {
                var name = reader["Name"] ?? throw new FormatException();
                reader.ReadStartElement("Pair");
                reader.ReadStartElement("Value");
                this[name] = (Presets)xmlSerializer.Deserialize(reader);
                reader.ReadEndElement();
                // reader.ReadEndElement();
            }
        }

        public void WriteXml(XmlWriter writer)
        {
            var xmlSerializer = new XmlSerializer(typeof(Presets));
            foreach (var entry in this)
            {
                writer.WriteStartElement("Pair");
                writer.WriteAttributeString("Name", entry.Key);
                writer.WriteStartElement("Value");
                xmlSerializer.Serialize(writer, entry.Value);
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
        }
    }
}
